﻿// LightNet - Lightweight .NET Framework
// Copyright (c) 2010 http://lightnet.codeplex.com

namespace System
{
    /// <summary>
    /// Represents errors that occur during application execution.
    /// </summary>
    public class Exception
    {
        /// <summary>
        /// Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.
        /// </summary>
        /// <returns>The HRESULT value.</returns>
        protected int HResult { get; set; }

        /// <summary>
        /// Gets the <see cref="T:System.Exception" /> instance that caused the current exception.
        /// </summary>
        /// <returns>An instance of Exception that describes the error that caused the current exception. The InnerException property returns the same value as was passed into the constructor, or a null reference (Nothing in Visual Basic) if the inner exception value was not supplied to the constructor. This property is read-only.</returns>
        public Exception InnerException { get; private set; }

        /// <summary>
        /// Gets a message that describes the current exception.
        /// </summary>
        /// <returns>The error message that explains the reason for the exception, or an empty string("").</returns>
        public virtual string Message { get; private set; }

        /// <summary>
        /// Gets a string representation of the frames on the call stack at the time the current exception was thrown.
        /// </summary>
        /// <returns>A string that describes the contents of the call stack, with the most recent method call appearing first.</returns>
        public virtual string StackTrace { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Exception" /> class.
        /// </summary>
        public Exception()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Exception" /> class with a specified error message.
        /// </summary>
        /// <param name="message">The message that describes the error.</param>
        public Exception(string message)
        {
            Message = message;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Exception" /> class with a specified error message and a reference to the inner exception that is the cause of this exception.
        /// </summary>
        /// <param name="message">The error message that explains the reason for the exception.</param>
        /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
        public Exception(string message, Exception innerException)
        {
            Message = message;
            InnerException = innerException;
        }

        /// <summary>
        /// When overridden in a derived class, returns the <see cref="T:System.Exception" /> that is the root cause of one or more subsequent exceptions.
        /// </summary>
        /// <returns>The first exception thrown in a chain of exceptions. If the <see cref="P:System.Exception.InnerException" /> property of the current exception is a null reference (Nothing in Visual Basic), this property returns the current exception.</returns>
        public virtual Exception GetBaseException()
        {
            var innerException = InnerException;
            var exception = this;
            while (innerException != null)
            {
                exception = innerException;
                innerException = innerException.InnerException;
            }
            return exception;
        }

        /// <summary>
        /// Gets the runtime type of the current instance.
        /// </summary>
        /// <returns>A <see cref="T:System.Type" /> object that represents the exact runtime type of the current instance.</returns>
        new public Type GetType()
        {
            return base.GetType();
        }

        /// <summary>
        /// Creates and returns a string representation of the current exception.
        /// </summary>
        /// <returns>A string representation of the current exception.</returns>
        public override string ToString()
        {
            throw new NotImplementedException();
        }

        internal void SetErrorCode(int hr)
        {
            HResult = hr;
        }
    }
}
